﻿using System;
using System.Reflection;

namespace Moven
{
	public static class ReflectionExtensions
	{
		public static TReturn GetPropertyValue<TReturn>(this object obj, string name, BindingFlags bindingFlags)
		{
			var property = obj.GetType().GetProperty(name, bindingFlags | BindingFlags.Instance);
			return (TReturn)property?.GetValue(obj);
		}

		public static TReturn GetStaticPropertyValue<TReturn>(this Type type, string name, BindingFlags bindingFlags)
		{
			var property = type.GetProperty(name, bindingFlags | BindingFlags.Static);
			return (TReturn)property?.GetValue(null);
		}

		public static TReturn GetFieldValue<TReturn>(this object obj, string name, BindingFlags bindingFlags)
		{
			var field = obj.GetType().GetField(name, bindingFlags | BindingFlags.Instance);
			return (TReturn)field?.GetValue(obj);
		}

		public static TReturn GetStaticFieldValue<TReturn>(this Type type, string name, BindingFlags bindingFlags)
		{
			var field = type.GetField(name, bindingFlags | BindingFlags.Static);
			return (TReturn)field?.GetValue(null);
		}

		public static TReturn CallMethod<TReturn>(this object obj, string name, BindingFlags bindingFlags,
			params object[] parameters)
		{
			var method = obj.GetType().GetMethod(name, bindingFlags | BindingFlags.Instance);
			return (TReturn)method?.Invoke(obj, parameters);
		}

		public static void CallMethod(this object obj, string name, BindingFlags bindingFlags,
			params object[] parameters)
		{
			var method = obj.GetType().GetMethod(name, bindingFlags | BindingFlags.Instance);
			method?.Invoke(obj, parameters);
		}

		public static TReturn CallStaticMethod<TReturn>(this Type type, string name, BindingFlags bindingFlags,
			params object[] parameters)
		{
			var method = type.GetMethod(name, bindingFlags | BindingFlags.Static);
			return (TReturn)method?.Invoke(null, parameters);
		}

		public static void CallStaticMethod(this Type type, string name, BindingFlags bindingFlags,
			params object[] parameters)
		{
			var method = type.GetMethod(name, bindingFlags | BindingFlags.Static);
			method?.Invoke(null, parameters);
		}
	}
}
